﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using LeafulWeiboSdk.Metadata;
using Newtonsoft.Json;

namespace LeafulWeiboSdk
{
    public class WeiboApp
    {
        #region 构造函数、属性
        private readonly CultureInfo _ic = CultureInfo.InvariantCulture;
        public string AppKey { get; set; }
        public string AppSecret { get; set; }
        public string AccessToken { get; set; }
        public string CallbackUrl { get; set; }
        
        public WeiboApp(string appKey, string appSecret, string callbackUrl, string accessToken = null)
        {
            AppKey = appKey;
            AppSecret = appSecret;
            CallbackUrl = callbackUrl;
            AccessToken = accessToken;
        }

        #endregion
        
        #region 授权

        /// <summary>
        /// 通过授权码来获取AccessToken
        /// </summary>
        /// <param name="authorizationCode"></param>
        /// <returns></returns>
        public async Task<AccessTokenMetadata> ReadAccessTokenByAuthorizationCodeAsync(string authorizationCode)
        {
            return await Swap.GetMetadataViaHttpPostAsync<AccessTokenMetadata>(WeiboApi.OAuth2.AccessToken,
                "client_id", AppKey,
                "client_secret", AppSecret,
                "grant_type", "authorization_code",
                "code", authorizationCode,
                "redirect_uri", CallbackUrl);
        }

        /// <summary>
        /// 验证AccessToken是否可用
        /// </summary>
        /// <returns>AccessToken信息</returns>
        public async Task<TokenInfoMetadata> VerifyAccessTokenValidAsync()
        {
            if (string.IsNullOrEmpty(AccessToken)) return new TokenInfoMetadata{ErrorMessage = "Token is null"};
            return await Swap.GetMetadataViaHttpPostAsync<TokenInfoMetadata>(WeiboApi.OAuth2.TokenInfo,
                "access_token", AccessToken);
        }

        public string GetAuthorizeUrl()
        {
            return string.Format("{0}?client_id={1}&redirect_uri={2}&response_type=code", WeiboApi.OAuth2.Authorize, AppKey, CallbackUrl);
        }

        #endregion

        #region 用户

        public async Task<UserMetadata> UserReadInfoByUid(string uid)
        {
            return await Swap.GetMetadataViaHttpGetAsync<UserMetadata>(WeiboApi.Users.Show,
                "access_token", AccessToken,
                "uid", uid);
        }

        #endregion

        #region 微博

        public enum TimelineType
        {
            Friends,Home,User,Public
        }

        /// <summary>
        /// 异步读取微博列表
        /// </summary>
        /// <param name="type">列表类型</param>
        /// <param name="sinceId">只读取此ID后的微博</param>
        /// <param name="maxId">只读取此ID前的微博</param>
        /// <param name="count">获取微博数量</param>
        /// <param name="page">获取微博页码</param>
        /// <param name="feature">获取微博类型</param>
        /// <returns>微博列表</returns>
        public async Task<StatusCollectionMetadata> StatusReadTimelineAsync(TimelineType type = TimelineType.Friends, 
            long? sinceId = null, long? maxId = null, int? count = null, int? page = null, StatusType? feature = null)
        {
            string api;
            switch (type)
            {
                case TimelineType.Friends:
                    api = WeiboApi.Statuses.FriendTimeline;
                    break;
                case TimelineType.Public:
                    api = WeiboApi.Statuses.PublicTimeline;
                    sinceId = null;
                    maxId = null;
                    page = null;
                    feature = null;
                    break;
                default:
                    api = WeiboApi.Statuses.FriendTimeline;
                    break;
            }
            return await Swap.GetMetadataViaHttpGetAsync<StatusCollectionMetadata>(api,
                "access_token", AccessToken,
                "since_id", sinceId,
                "max_id", maxId,
                "count", count,
                "page", page,
                "feature", ((int?) feature));
        }

        public enum EmotionsType 
        {
            face,ani,cartoon 
        }

        public enum EmotionsLanguage
        {
            cnname,twname
        }
        
        /// <summary>
        /// 发一条微博
        /// </summary>
        /// <param name="postText">正文（不超过140字）</param>
        /// <param name="imgPath">（可选）图片</param>
        /// <returns></returns>
        public async Task<StatusMetadata> StatusWriteAsync(string postText, string imgPath = null)
        {
            if (imgPath == null)
            {
                return await Swap.GetMetadataViaHttpPostAsync<StatusMetadata>(WeiboApi.Statuses.Update,
                    "access_token", AccessToken,
                    "status", postText);
            }
            else
            {
                if (!File.Exists(imgPath)) return new StatusMetadata() {ErrorMessage = "Photo file does not exist."};
                if (new FileInfo(imgPath).Length > 5 * 1021 * 1024) return new StatusMetadata { ErrorMessage = "Photo is too large." }; // 5MB limit
                return await Swap.GetMetadataViaHttpPostAsync<StatusMetadata>(WeiboApi.Statuses.Upload,
                    "access_token", AccessToken,
                    "status", Swap.UrlEncode(postText),
                    "pic", await Swap.FileEncodeAsync(imgPath));
            }
        }
        
        #endregion

        #region 评论

        public async Task<CommentCollectionMetadata> CommentsReadById(long id, long? sinceId, long? maxId, int? count, int? page)
        {
            return await Swap.GetMetadataViaHttpGetAsync<CommentCollectionMetadata>(WeiboApi.Comments.Show,
                "id", id,
                "since_id", sinceId,
                "max_id", maxId,
                "count", count,
                "page", page);
        } 

        #endregion

        #region 收藏

        public async Task<StatusMetadata> FavouriteAddAsync(string id)
        {
            return await Swap.GetMetadataViaHttpPostAsync<StatusMetadata>(WeiboApi.Favorites.Create,
                "access_token", AccessToken,
                "id", id);
        }

        public async Task<StatusMetadata> FavouriteDeleteAsync(string id)
        {
            return await Swap.GetMetadataViaHttpPostAsync<StatusMetadata>(WeiboApi.Favorites.Destroy,
                "access_token", AccessToken,
                "id", id);
        }

        #endregion

        #region 其他

        /// <summary>
        /// 获取官方表情
        /// </summary>
        /// <param name="type"></param>
        /// <param name="lang"></param>
        /// <returns></returns>
        public async Task<List<EmotionMetadata>> EmotionReadAsync(EmotionsType? type = null,
            EmotionsLanguage? lang = null)
        {
            try
            {
                var json = await Swap.HttpGetWeiboJsonAsync(WeiboApi.Emotions,
                    "access_token", AccessToken,
                    "type", type,
                    "language", lang);
                return JsonConvert.DeserializeObject<List<EmotionMetadata>>(json);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                return null;
            }

        }

        #endregion

    }
}
